#pragma once
#include<iostream>
using namespace std;
class Node {
	friend class Tree;
public:
	Node() {
		left = right = nullptr;
		val = 0;
		key = 0;
		height = 0;
	}
	Node(int k,int v) {
		left = right = nullptr;
		val = v;
		key = k;
		height = 0;
	}
	int max(int a, int b) {
	return a > b ? a : b;
	}
	void  set_left_by_node(Node* n) {
		left = n;
	}
	void set_right_by_node(Node* n) {
		right = n;
	}
	void set_left_by_value(int k,int v) {
		Node* n = new Node(k,v);
		left = n;
	}
	void set_right_by_value(int k,int v) {
		Node* n = new Node(k,v);
		right = n;
	} 
	void set_val(int v){
		val = v;
	}
	void set_key(int k) {
		key = k;
	}
	void set_height(int h) {
		height = h;
	}
	int get_val() {
		return val;
	}
	int get_key() {
		return key;
	}
	int get_height() {
		return get_high(this);
	}
	virtual Node* get_left(){
		return left;
	}
	virtual Node* get_right(){
		return right;
	}
	virtual int get_high(Node* n) {
		if (n == nullptr )
			return 0;
		return max(get_high(n->get_left()), get_high(n->get_right())) + 1;
	}
	virtual int get_high() {
		return get_high(this);
	}
//private:
	Node* left;
	Node* right;
	int val;
	int key;
	int height;
};
class Tree {
public:
	Tree() {
		root = nullptr;
	}
	virtual void insert(int k, int v) = 0;
	virtual void insert(int* x, int n) = 0;
	virtual void delete_by_key(int k) = 0;
	virtual Node* get_root() {
		return root;
	}
	Node* root;
	int size;
};